package com.xl.bigdata.es.search;

import com.xl.bigdata.es.xpack.ESXpackRestHighLevelClient;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;

import java.io.IOException;

/**
 * @program: IAEngine
 * @description:
 *  Search_after
 *  官方文档：https://www.elastic.co/guide/en/elasticsearch/reference/current/paginate-search-results.html
 *  滚动查询，实时的深度分页，支持一页一页查询，不支持跳页查询，目前深度分页的最优解决方案
 * @author: XL.Gao
 * @create: 2021-08-26 18:23
 **/
public class SearchAfterAPI {

    public static final String UID = "_id";

    public static final int TIMEOUT = 10;

    public static Object[] searchAfterAPI(RestHighLevelClient client, int size, String index, Object[] obj){

        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        searchSourceBuilder.query(QueryBuilders.termQuery("citycomple", "青岛"));
        searchSourceBuilder.size(size);
        searchSourceBuilder.sort(UID, SortOrder.DESC);
        searchSourceBuilder.timeout(TimeValue.timeValueSeconds(TIMEOUT));

        if(obj != null){
            searchSourceBuilder.searchAfter(obj);
        }

        searchRequest.source(searchSourceBuilder);

        try {
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

            SearchHit[] hits = searchResponse.getHits().getHits();
            if(hits != null && size == hits.length - 1){
                obj = hits[hits.length - 1].getSortValues();
            } else {
                obj = null;
            }
            System.out.println(hits.length);
            System.out.println(hits[hits.length - 1].getSortValues());
            System.out.println(hits[hits.length - 1].getSourceAsString());
        } catch (IOException e) {
            e.printStackTrace();
        }

        return obj;

    }

    public static void main(String[] args) {

        ESXpackRestHighLevelClient.getRestHighLevelClient();

        long l = System.currentTimeMillis();
        Object[] objects = searchAfterAPI(ESXpackRestHighLevelClient.getRestHighLevelClient(), 100, "address_base", null);
        System.out.println("初次 -- " + (System.currentTimeMillis() - l));

        for (int i = 0; i < 15; i++) {
            long l1 = System.currentTimeMillis();
            objects = searchAfterAPI(ESXpackRestHighLevelClient.getRestHighLevelClient(), 100, "address_base", objects);
            System.out.println(i + " -- " + (System.currentTimeMillis() - l1));
        }

        ESXpackRestHighLevelClient.closeRestHighLevelClient();
    }

}
